﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Pavilion.DesignerTool.ViewTools;
using Pavilion.DesignerTool.ViewTools.ConnectableListBox;

namespace Pavilion.DesignerTool
{
    /// <summary>
    /// Interaction logic for NodeScriptView.xaml
    /// </summary>
    public partial class NodeScriptView : UserControl
    {
        public static readonly DependencyProperty ConnectableListBoxProperty = DependencyProperty.Register("ConnectableListBox", typeof(ConnectableListBox), typeof(NodeScriptView));

        public ConnectableListBox ConnectableListBox { get { return (ConnectableListBox)GetValue(ConnectableListBoxProperty); } set { } }
        private NodeScriptViewModel ViewModel { get { return (NodeScriptViewModel)base.DataContext; } }

        public NodeScriptView()
        {
            InitializeComponent();
        }

        private void StepIntoMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.StepIntoNode(connectableListBox.SelectedConnectableItem);
        }

        private void StepOut_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel != null ? ViewModel.CanStepOut : false;
        }

        private void StepOut_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.StepOutOfNode();
        }

        private void NodeItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ViewModel.StepIntoNode(connectableListBox.SelectedConnectableItem);
        }

        private void NewAnimationNode_MenuItemClick(object sender, RoutedEventArgs e)
        {
            ViewModel.AddNewAnimationNode();
        }

        private void NewContainerNode_MenuItemClick(object sender, RoutedEventArgs e)
        {
            ViewModel.AddNewContainerNode();
        }

        private void NewLoadNode_MenuItemClick(object sender, RoutedEventArgs e)
        {
            ViewModel.AddNewLoadNode();
        }

        private void NewDefaultNode_MenuItemClick(object sender, RoutedEventArgs e)
        {
            ViewModel.AddNewDefaultNode();
        }

        private void RemoveLink_MenuItemClick(object sender, RoutedEventArgs e)
        {
            ViewModel.RemoveLink(connectableListBox.SelectedItem as LinkWrapper);
        }

        private void RemoveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            object[] array = new object[connectableListBox.SelectedItems.Count];
            connectableListBox.SelectedItems.CopyTo(array, 0);
            IEnumerable<NodeBaseWrapper> selectedNodes = array.Where((item) => item is NodeBaseWrapper).Select((item) => item as NodeBaseWrapper);

            ViewModel.RemoveNodes(selectedNodes);
        }

        private void Dragger_ItemDragged(object sender, RoutedEventArgs e)
        {
            DragAwareListBoxItem draggingListBox = e.OriginalSource as DragAwareListBoxItem;

            if (draggingListBox != null)
                draggingListBox.UpdatePosition();
        }

        private void CopyMenuItem_Click(object sender, RoutedEventArgs e)
        {
            object[] array = new object[connectableListBox.SelectedItems.Count];
            connectableListBox.SelectedItems.CopyTo(array, 0);

            ViewModel.CopySelectedItems(array);
        }

        private void PasteMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.Paste();
        }

        private void AddLinkMenuItem_Click(object sender, RoutedEventArgs e)
        {
            var item = connectableListBox.ItemContainerGenerator.ContainerFromItem((sender as FrameworkElement).DataContext);

            ConnectionManager.BeginConnection(item as ListBoxItem, (startItem, endItem) =>
            {
                NodeBaseWrapper startNode = startItem.DataContext as NodeBaseWrapper;
                NodeBaseWrapper endNode = endItem.DataContext as NodeBaseWrapper;

                ViewModel.AddLink(startNode, endNode);
            });
        }

        private void ReconnectMenuItem_Click(object sender, RoutedEventArgs e)
        {
            var linkWrapper = (sender as FrameworkElement).DataContext as LinkWrapper;
            var item = connectableListBox.ItemContainerGenerator.ContainerFromItem(linkWrapper.Start);

            OpenCriteria openCriteria = linkWrapper.OpenCriteria;
            IEnumerable<ILock> lockCollection = linkWrapper.LockWrapperCollection.Select(x => x.Lock).ToArray();
            
            ConnectionManager.BeginConnection(item as ListBoxItem, (startItem, endItem) =>
            {
                NodeBaseWrapper startNode = startItem.DataContext as NodeBaseWrapper;
                NodeBaseWrapper endNode = endItem.DataContext as NodeBaseWrapper;

                ViewModel.AddLink(startNode, endNode, lockCollection, openCriteria);
            });

            ViewModel.RemoveLink(linkWrapper);
        }
    }
}
